A week of fixes | This Week in Rails
ActiveRecordに関する変更です
SQLを生成するライブラリーで、ActiveRecordがSQLを生成する際に内部的に使われています。
Arelを使いこなせるようになると複雑なSQLを文字列として実装しなくて良くなるため、ActiveRecordの生成するSQLと親和性の高いSQLを組み立てられるようになります。
このArelをつかってテーブルをUNIONする際に、シンタックスエラーとなるクエリが組み立てられるケースがありました
具体的にはORDER BY句やLIMIT句を含むクエリをUNIONする際に問題が発生していました
code:rb
t = Arel::Table.new(:users)
working = t.project(t:id).union(t.project(t:id)) working.to_sql
# => "( SELECT users.id FROM users UNION SELECT users.id FROM users )"
ActiveRecord::Base.connection.exec_query(working.to_sql)
with_limit = t.project(t:id).take(1).union(t.project(t:id)) with_limit.to_sql
# => "( SELECT users.id FROM users LIMIT 1 UNION SELECT users.id FROM users )"
ActiveRecord::Base.connection.exec_query(with_limit.to_sql)
# ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR: syntax error at or near "UNION"
# LINE 1: ( SELECT "users"."id" FROM "users" LIMIT 1 UNION SELECT "use...
期待されるクエリは次のとおりです
code:sql
( ( SELECT "users"."id" FROM "users" LIMIT 1 ) UNION SELECT "users"."id" FROM "users" )
前半部分の文を丸括弧で括ってほしいということですね
今回のプルリクエストでは上述の「期待されるクエリ」が組み立てられるように修正を行なっています
ActiveJobに関する変更です
先週紹介したプルリクエストの中に「トランザクションがコミットされるまでジョブのエンキューを遅延するようになった」と説明したものがありました
そのプルリクエストに対してあのあとフィードバックコメントがありまして、今回のプルリクエストはそのフィードバックに基づく変更です
というのも、以前は Job.perform_later がキューに入れられたジョブのインスタンスを返していました
ところが先日のプルリクエストでエンキューが遅延されるようになり、Job.perform_later は nil を返すようになりました
この挙動変更により問題が発生するケースがありそうですね
今回のプルリクエストでは Job.perform_later がジョブのインスタンスを返すように変更されています
ただし、ジョブがエンキューされるのはトランザクションがコミットされたあとなので、もし必要ならジョブのインスタンスを保持しておいて #successfully_enqueued? メソッドでエンキューされたかどうかを確認しましょう